home *** CD-ROM | disk | FTP | other *** search
/ PC World Komputer 2010 April / PCWorld0410.iso / hity wydania / Ubuntu 9.10 PL / karmelkowy-koliberek-desktop-9.10-i386-PL.iso / casper / filesystem.squashfs / usr / share / pyshared / Onboard / Keyboard.py < prev    next >
Text File  |  2009-10-01  |  8KB  |  234 lines

  1. import gobject
  2. import gtk
  3. import string
  4. import virtkey
  5.  
  6. from Onboard.KeyGtk import *
  7. from Onboard import KeyCommon
  8.  
  9. try:
  10.     from Onboard.utils import run_script, get_keysym_from_name, dictproperty
  11. except DeprecationWarning:
  12.     pass
  13.  
  14. ### Config Singleton ###
  15. from Onboard.Config import Config
  16. config = Config()
  17. ########################
  18.  
  19. class Keyboard:
  20.     "Cairo based keyboard widget"
  21.  
  22.     # When set to a pane, the pane overlays the basePane.
  23.     activePane = None 
  24.     active = None #Currently active key
  25.     scanningActive = None # Key currently being scanned.
  26.     altLocked = False 
  27.     scanning_x = None
  28.     scanning_y = None
  29.  
  30. ### Properties ###
  31.     
  32.     _mods = {1:0,2:0, 4:0,8:0, 16:0,32:0,64:0,128:0}
  33.     def _get_mod(self, key):
  34.         return self._mods[key]
  35.     def _set_mod(self, key, value):
  36.         self._mods[key] = value
  37.         self._on_mods_changed()
  38.     mods = dictproperty(_get_mod, _set_mod)
  39.     """ The number of pressed keys per modifier """
  40.  
  41. ##################
  42.  
  43.     def __init__(self):
  44.         self.vk = virtkey.virtkey()
  45.  
  46.  
  47.         #List of keys which have been latched.  
  48.         #ie. pressed until next non sticky button is pressed.
  49.         self.stuck = [] 
  50.         self.tabKeys = []
  51.         self.panes = [] # All panes except the basePane
  52.         self.tabKeys.append(BaseTabKey(self, config.SIDEBARWIDTH))
  53.         self.queue_draw()
  54.         
  55.        
  56.     def set_basePane(self, basePane):
  57.         self.basePane = basePane #Pane which is always visible
  58.  
  59.     def add_pane(self, pane):
  60.         self.panes.append(pane)
  61.         self.tabKeys.append(TabKey(self, config.SIDEBARWIDTH, pane))
  62.  
  63.     def utf8_to_unicode(self,utf8Char):
  64.         return ord(utf8Char.decode('utf-8'))
  65.     
  66.     def scan_tick(self): #at intervals scans across keys in the row and then down columns.
  67.         if self.scanningActive:
  68.             self.scanningActive.beingScanned = False
  69.         
  70.         if self.activePane:
  71.             pane = self.activePane
  72.         else:
  73.             pane = self.basePane
  74.         
  75.         if not self.scanning_y == None:
  76.             self.scanning_y = (self.scanning_y + 1) % len(pane.columns[self.scanning_x])
  77.         else:
  78.             self.scanning_x = (self.scanning_x + 1) % len(pane.columns)
  79.         
  80.         if self.scanning_y == None:
  81.             y = 0
  82.         else:
  83.             y = self.scanning_y
  84.         
  85.         self.scanningActive = pane.columns[self.scanning_x][y]
  86.         
  87.         self.scanningActive.beingScanned = True
  88.         self.queue_draw()
  89.         
  90.         return True
  91.         
  92.     def is_key_pressed(self,key, widget, event):
  93.         if(key.pointWithinKey(widget, event.x, event.y)):
  94.             self.press_key(key)
  95.     
  96.     def _on_mods_changed(self):
  97.         raise NotImplementedException()
  98.  
  99.     def press_key(self, key):
  100.         if not key.on:
  101.             if self.mods[8]:
  102.                 self.altLocked = True
  103.                 self.vk.lock_mod(8) 
  104.  
  105.             if key.sticky == True:
  106.                     self.stuck.append(key)
  107.                     
  108.             else:
  109.                 self.active = key #Since only one non-sticky key can be pressed at once.
  110.             
  111.             key.on = True
  112.             
  113.             self.locked = []
  114.             if key.action_type == KeyCommon.CHAR_ACTION:
  115.                 self.vk.press_unicode(self.utf8_to_unicode(key.action))
  116.             
  117.             elif key.action_type == KeyCommon.KEYSYM_ACTION:
  118.                 self.vk.press_keysym(key.action)
  119.             elif key.action_type == KeyCommon.KEYPRESS_NAME_ACTION:
  120.                 self.vk.press_keysym(get_keysym_from_name(key.action))
  121.             elif key.action_type == KeyCommon.MODIFIER_ACTION:
  122.                 mod = key.action
  123.                 
  124.                 if not mod == 8: #Hack since alt puts metacity into move mode and prevents clicks reaching widget.
  125.                     self.vk.lock_mod(mod)
  126.                 self.mods[mod] += 1
  127.             elif key.action_type == KeyCommon.MACRO_ACTION:
  128.                 try:
  129.                     mString = unicode(config.snippets[string.atoi(key.action)])
  130. # If mstring exists do the below, otherwise the code in finally should always 
  131. # be done.
  132.                     if mString:
  133.                         for c in mString:
  134.                             self.vk.press_unicode(ord(c))
  135.                             self.vk.release_unicode(ord(c))
  136.                         return
  137.                             
  138.                 except IndexError:
  139.                     pass
  140.  
  141.                 dialog = gtk.Dialog("No snippet", self.parent, 0, 
  142.                         ("_Save snippet", gtk.RESPONSE_OK, 
  143.                          "_Cancel", gtk.RESPONSE_CANCEL))
  144.                 dialog.vbox.add(gtk.Label(
  145.                     "No snippet for this button,\nType new snippet"))
  146.                 
  147.                 macroEntry = gtk.Entry()                
  148.             
  149.                 dialog.connect("response", self.cb_dialog_response,string.atoi(key.action), macroEntry)
  150.                 
  151.                 macroEntry.connect("activate", self.cb_macroEntry_activate,string.atoi(key.action), dialog)
  152.                 dialog.vbox.pack_end(macroEntry)
  153.  
  154.                 dialog.show_all()
  155.  
  156.             elif key.action_type == KeyCommon.KEYCODE_ACTION:
  157.                 self.vk.press_keycode(key.action);
  158.                 
  159.             elif key.action_type == KeyCommon.SCRIPT_ACTION:
  160.                 run_script(key.action)
  161.             else:
  162.                 for k in self.tabKeys: # don't like this.
  163.                     if k.pane == self.activePane:
  164.                         k.on = False
  165.                         k.stuckOn = False
  166.                 
  167.                 self.activePane = key.pane
  168.         else:
  169.             if key in self.stuck:
  170.                 key.stuckOn = True
  171.                 self.stuck.remove(key)
  172.             else:
  173.                 key.stuckOn = False
  174.                 self.release_key(key)
  175.  
  176.         self.queue_draw()
  177.             
  178.         
  179.     def cb_dialog_response(self, widget, response, macroNo,macroEntry):
  180.         self.set_new_macro(macroNo, response, macroEntry, widget)
  181.  
  182.     def cb_macroEntry_activate(self,widget,macroNo,dialog):
  183.         self.set_new_macro(macroNo, gtk.RESPONSE_OK, widget, dialog)
  184.     
  185.     def set_new_macro(self,macroNo,response,macroEntry,dialog):
  186.         if response == gtk.RESPONSE_OK: 
  187.             config.set_snippet(macroNo, macroEntry.get_text())
  188.  
  189.         dialog.destroy()
  190.     
  191.     def release_key(self,key):
  192.         if key.action_type == KeyCommon.CHAR_ACTION:
  193.             self.vk.release_unicode(self.utf8_to_unicode(key.action))
  194.         elif key.action_type == KeyCommon.KEYSYM_ACTION:
  195.             self.vk.release_keysym(key.action)
  196.         elif key.action_type == KeyCommon.KEYPRESS_NAME_ACTION:
  197.             self.vk.release_keysym(get_keysym_from_name(key.action))
  198.         elif key.action_type == KeyCommon.MODIFIER_ACTION:
  199.             mod = key.action
  200.             
  201.             if not mod == 8:        
  202.                 self.vk.unlock_mod(mod)
  203.             
  204.             self.mods[mod] -= 1
  205.             
  206.         elif key.action_type == KeyCommon.KEYCODE_ACTION:
  207.             self.vk.release_keycode(key.action);
  208.             
  209.         elif (key.action_type == KeyCommon.MACRO_ACTION or 
  210.               key.action_type == KeyCommon.SCRIPT_ACTION):
  211.             pass
  212.                 
  213.                 
  214.         else:
  215.             self.activePane = None
  216.         
  217.         
  218.         if self.altLocked:
  219.             self.altLocked = False
  220.             self.vk.unlock_mod(8)
  221.         
  222.         gobject.idle_add(self.release_key_idle,key) #Makes sure we draw key pressed before unpressing it. 
  223.  
  224.     def release_key_idle(self,key):
  225.         key.on = False
  226.         self.queue_draw()
  227.         return False
  228.  
  229.     def clean(self):
  230.         for pane in [self.basePane,] + self.panes:
  231.             for group in pane.key_groups.values():
  232.                 for key in group:
  233.                     if key.on: self.release_key(key)
  234.